package com.cloudfun.campusshare.device.protocol.decoder;

import com.cloudfun.campusshare.device.protocol.response.GxyState;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.BiConsumer;

/**
 * 滚筒洗衣机
 * Created by Huqin on 2020/1/3
 */
public class GxyStateMessageDecoder extends ByteToMessageDecoder<GxyState> {

    private List<FieldDecoder<GxyState>> fieldDecoderList;

    public GxyStateMessageDecoder() {
        fieldDecoderList = new ArrayList<>();
        // 洗衣程序 washprog
        fieldDecoderList.add(new EnumFieldDecoder<>(0, 1, GxyState::setLaundryCycleCW, this.washTypeMap()));
        // 设定的附加控制功能 additionA
        fieldDecoderList.add(new BitSwitchFieldDecoder<>(2, 1, this.additionFunctionMap()));
        // 程序运行的阶段 stage
        fieldDecoderList.add(new EnumFieldDecoder<>(4, 1, GxyState::setCyclePhaseCW, this.stageMap()));
        // 状态 state1
        fieldDecoderList.add(new BitSwitchFieldDecoder<>(5, 1, this.state1Map()));
        // 状态 state2
        fieldDecoderList.add(new BitSwitchFieldDecoder<>(6, 1, this.state2Map()));

        // 当前剩余/预约时间的小时部分 remainprectime Hour
        fieldDecoderList.add(new DigitFieldDecoder<>(7, 1, GxyState::setRemainingTimeHH));
        // 当前剩余/预约时间的分钟部分 remainprectime Minute
        fieldDecoderList.add(new DigitFieldDecoder<>(8, 1, GxyState::setRemainingTimeMM));
        // 提示信息 message
        fieldDecoderList.add(new EnumFieldDecoder<>(9, 1, GxyState::setMessage, this.messageMap()));
        // 漂洗次数 sptimes
        fieldDecoderList.add(new DigitFieldDecoder<>(25, 1, GxyState::setSpTimes));
        // 脱水时间 spin time
        fieldDecoderList.add(new DigitFieldDecoder<>(27, 1, GxyState::setSpinTime));
        // 主洗时间 main wash time
        fieldDecoderList.add(new DigitFieldDecoder<>(29, 1, GxyState::setMainWashTime));
        // 脱水转速 SpinRPM
        fieldDecoderList.add(new DigitFieldDecoder<>(30, 2, GxyState::setSpinSpeed));
    }

    @Override
    protected List<FieldDecoder<GxyState>> fieldDecoderList() {
        return fieldDecoderList;
    }

    @Override
    protected GxyState prepare() {
        return new GxyState();
    }

    private Map<String, String> messageMap() {
        Map<String, String> messageMap = new HashMap<>();
        messageMap.put("01", "衣服已洗完");
        return messageMap;
    }

    private Map<Integer, BiConsumer<GxyState, Boolean>> state2Map() {
        Map<Integer, BiConsumer<GxyState, Boolean>> stage2Map = new HashMap<>();
        stage2Map.put(0, GxyState::setDoorClosed);
        return stage2Map;
    }

    private Map<Integer, BiConsumer<GxyState, Boolean>> state1Map() {
        Map<Integer, BiConsumer<GxyState, Boolean>> stage1Map = new HashMap<>();
        stage1Map.put(5, GxyState::setDoorLocked);
        stage1Map.put(6,  GxyState::setLaundryCycleStatus);
        stage1Map.put(7, GxyState::setStarted);
        return stage1Map;
    }

    private Map<String, Integer> stageMap() {
        Map<String, Integer> stageMap = new HashMap<>();
        stageMap.put("00", 0);//待机
        stageMap.put("01", 1);//称重
        stageMap.put("03", 3);//洗涤进水
        stageMap.put("04", 4);//洗涤加热
        stageMap.put("05", 5);//洗涤
        stageMap.put("06", 6);//洗涤排水
        stageMap.put("07", 7);//中间脱水
        stageMap.put("08", 8);//漂洗进水
        stageMap.put("09", 9);//漂洗
        stageMap.put("0A", 10);//漂洗排水
        stageMap.put("0B", 11);//最终脱水
        stageMap.put("0E", 14);//结束
        return stageMap;
    }

    private Map<Integer, BiConsumer<GxyState, Boolean>> additionFunctionMap() {
        Map<Integer, BiConsumer<GxyState, Boolean>> additionFunctionMap = new HashMap<>();
        additionFunctionMap.put(4, GxyState::setSpeedUpStatus);
        additionFunctionMap.put(5, GxyState::setQuietRinseStatus);
        additionFunctionMap.put(6, GxyState::setHeatingStatus60);
        additionFunctionMap.put(7, GxyState::setHeatingStatus40);
        return additionFunctionMap;
    }

    private Map<String, Integer> washTypeMap() {
        Map<String, Integer> washTypeMap = new HashMap<>();
        washTypeMap.put("0D", 5);//桶自洁
        washTypeMap.put("1C", 4);//单脱
        washTypeMap.put("1F", 1);//冷水（标准）
        washTypeMap.put("20", 2);//温水（快速）
        washTypeMap.put("21", 3);//热水（大物）
        washTypeMap.put("22", 8);//轻柔
        return washTypeMap;
    }
}
